package cn.com.hori.cms.interceptor;

import cn.com.hori.cms.dao.TokenRepository;
import cn.com.hori.cms.entities.AdminToken;
import cn.com.hori.cms.model.CommonResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @author 刘艺
 * @date 2018/3/8 14:07
 */
@Service
public class ManageTokenInterceptor extends HandlerInterceptorAdapter {

    private static Logger logger = LoggerFactory.getLogger(ManageTokenInterceptor.class);


    private TokenRepository tokenRepository;

    public static final String REQ_PARAM_ACCESS_TOKEN = "access_token";

    private ObjectMapper mapper = null;

    public ManageTokenInterceptor(TokenRepository tokenRepository) {
        super();
        mapper = new ObjectMapper();
        this.tokenRepository = tokenRepository;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.debug("需验证token服务:" + request.getRequestURI());
        // TOKEN
        String accessToken = request.getParameter(REQ_PARAM_ACCESS_TOKEN);

        logger.debug("current access_token=" + accessToken);

        CommonResponse data = new CommonResponse();

        AdminToken adminToken = null;
        boolean result = true;
        // token为空
        if (StringUtils.isEmpty(accessToken)) {
            data.setCode(CommonResponse.NOT_AUTHORIZED_CODE);
            data.setMsg(CommonResponse.NOT_AUTHORIZED_MSG);
            logger.error("token参数为空：" + CommonResponse.NOT_AUTHORIZED_MSG);
            result = false;
        } else {
            // 包含token，进行token验证
            adminToken = tokenRepository.findTokenByAccessToken(accessToken);
            if (adminToken == null) {
                // 无对应token 或 token已经失效
                data.setCode(CommonResponse.TOKEN_NOT_AVAILABLE_CODE);
                data.setMsg(CommonResponse.TOKEN_NOT_AVAILABLE_MSG);
                logger.error("无对应token=：" + accessToken + CommonResponse.TOKEN_NOT_AVAILABLE_MSG);
                result = false;
            } else {
                if (System.currentTimeMillis() - adminToken.getThisTimestamp() > adminToken.getUsefulLife()) {
                    tokenRepository.delete(adminToken);
                    // 无对应token 或 token已经失效
                    data.setCode(CommonResponse.TOKEN_NOT_AVAILABLE_CODE);
                    data.setMsg(CommonResponse.TOKEN_NOT_AVAILABLE_MSG);
                    logger.error("失效token=：" + accessToken + CommonResponse.TOKEN_NOT_AVAILABLE_MSG);
                    result = false;
                } else {
                    if (System.currentTimeMillis() - adminToken.getThisTimestamp() > 6000000) {
                        // token有效期的一个半到两个小时区间内有访问则加一次token有效时长
                        adminToken.setThisTimestamp(System.currentTimeMillis());
                        tokenRepository.save(adminToken);
                    }
                }
            }
        }
        if (!result) {
            PrintWriter printWriter = response.getWriter();
            // 验证未通过
            response.setContentType("text/json");
            response.setCharacterEncoding("UTF-8");
            printWriter.print(mapper.writeValueAsString(data));
            printWriter.flush();
            printWriter.close();
            return false;
        }
        // 有对应token
        logger.debug("本次请求的token为：" + adminToken);
        return super.preHandle(request, response, handler);
    }
}